﻿using System;
using System.Text.RegularExpressions;
using umbraco.cms.businesslogic.member;
using umbraco.presentation.nodeFactory;

namespace uForum.Library
{
	public class Utills
	{
		private static Regex _tags = new Regex("<[^>]*(>|$)", RegexOptions.Singleline | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
		private static Regex _whitelist = new Regex(@"
            ^</?(a|b(lockquote)?|code|em|h(1|2|3)|i|li|ol|p(re)?|s(ub|up|trong|trike)?|ul)>$
            |^<(b|h)r\s?/?>$
            |^<a[^>]+>$
            |^<img[^>]+/?>$",
			RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace |
			RegexOptions.ExplicitCapture | RegexOptions.Compiled);

		/// <summary>
		/// sanitize any potentially dangerous tags from the provided raw HTML input using 
		/// a whitelist based approach, leaving the "safe" HTML tags
		/// </summary>
		public static string Sanitize(string html)
		{

			var tagname = "";
			Match tag;
			var tags = _tags.Matches(html);

			// iterate through all HTML tags in the input
			for (int i = tags.Count - 1; i > -1; i--)
			{
				tag = tags[i];
				tagname = tag.Value.ToLower();

				if (!_whitelist.IsMatch(tagname))
				{
					// not on our whitelist? I SAY GOOD DAY TO YOU, SIR. GOOD DAY!
					html = html.Remove(tag.Index, tag.Length);
				}
				else if (tagname.StartsWith("<img"))
				{
					// detailed <img> tag checking
					if (!IsMatch(tagname,
						@"<img\s
              src=""https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+""
              (\swidth=""\d{1,3}"")?
              (\sheight=""\d{1,3}"")?
              (\salt=""[^""]*"")?
              (\stitle=""[^""]*"")?
              \s?/?>"))
					{
						html = html.Remove(tag.Index, tag.Length);
					}
				}

			}

			return html;
		}


		/// <summary>
		/// Utility function to match a regex pattern: case, whitespace, and line insensitive
		/// </summary>
		private static bool IsMatch(string s, string pattern)
		{
			return Regex.IsMatch(s, pattern, RegexOptions.Singleline | RegexOptions.IgnoreCase |
				RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture);
		}

		public static Member GetMember(int id)
		{
			Member m = Member.GetMemberFromCache(id);
			if (m == null)
				m = new Member(id);

			return m;
		}

		public static string GetPropertyRecursive(int id, string alias)
		{
			Node node = new Node(id);
			string[] nodeIds = node.Path.Split(',');
			for (int i = nodeIds.Length-1; i >= 0; i--)
			{
				int nodeid = Convert.ToInt32(nodeIds[i]);
				if(nodeid.Equals(-1)) return null;
				string value = GetSafeValue(new Node(nodeid), alias);
				if(!string.IsNullOrEmpty(value)) return value;
			}
			return null;
		}

		private static string GetSafeValue(Node node, string alias)
		{
			Property property = node.GetProperty(alias);
			if (property == null) return string.Empty;
			return property.Value;
		}
	}
}
